<?php
//主题基类
abstract class Subject {
	//观察者列表
	private $arrObserver = array();
	//增加一个观察者
	public function attach(&$observer){
		$this->arrObserver[] = $observer;
	}
	//去除一个观察者
	public function detach(&$observer){
		for($i=0; $i<count($this->$arrObserver); $i++){
			$objTemp = $this->$arrObserver[$i];
			if($observer === $objTemp){
				array_splice($this->$arrObserver,$i,1);
				break;
			}
		}
	}
	//通知观察者更新
	public function notifyObservers(){
		foreach ($this->arrObserver as $observer){
			$observer->update();
		}
	}	
	//获取主题信息
	public abstract function getSubject();
}
//银行柜台类
class Counter extends Subject {
	//当前业务号
	private $bizNo = "";
	//柜台名称
	private $name = "";
	//构造函数
	public function __construct($name){
		$this->name = $name;
	}
	//获取当前业务号
	public function getBizNo(){
		return $this->bizNo;
	}
	//设置当前业务号
	public function setBizNo($bizNo){
		$this->bizNo = $bizNo;
	}
	//获取主题信息
	public function getSubject(){
		return  "请" + $this->bizNo . "号到" . $this->name . "号柜台办理业务";
	}
}
//管理部门类
class Manager extends Subject{
	//管理部门名称
	private $name = "";
	//构造函数
	public function __construct($name){
		$this->name = $name;
	}
	//获取主题信息
	public function getSubject(){
		return $this->name . "发布最新紧急公告";
	}
}
//观察者基类
abstract class Observer {
	protected $name = "";
	protected $subject = "";
	//构造函数
	public function __construct($name,$subject){
		$this->name = $name;
		$this->subject = $subject;
	}
	//更新信息
	public abstract function update();
}
//小显示屏类
class SmallScreen extends Observer{
	//构造函数
	public function __construct($name,$subject ){
		parent::__construct($name,$subject);
	}
	//更新显示屏
	public function update(){
		echo $this->name . ":" . $this->subject->getSubject();
	}	
}
//音箱类
class Speaker extends Observer{
	//构造函数
	public function __construct($name,$subject){
		parent::__construct($name,$subject);
	}
	//更新音响
	public function update(){
		echo $this->name . ":" . $this->subject->getSubject();
	}	
}
//业务系统类
class BankBiz {
	public static function execute() {
		//银行柜台
		$counter = new Counter("1号柜台");
		//1,2号小屏、3号音箱
		$smallScreen1 = new SmallScreen("1号小屏",$counter);
		$smallScreen2 = new SmallScreen("2号小屏",$counter);
		$speaker = new Speaker("3号音箱",$counter);
		//银行柜台加入观察者
		$counter->attach($smallScreen1);
		$counter->attach($smallScreen2);
		$counter->attach($speaker);
		//9号办理业务
		$counter->setBizNo("9");
		//通知更新
		$counter->notifyObservers();
		
		//管理部门
		$manager = new Manager("风险控制部");	
		//1号小屏
		$smallScreen1 = new SmallScreen("1号小屏",$manager);		
		//管理部门加入观察者
		$manager->attach($smallScreen1);
		//通知更新
		$manager->notifyObservers();		
	}
}
BankBiz::execute();
?>
